
package cn.yunyichina.scheduler.jobs.common.hash;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleHashTableNameGenerator {

    private static final Logger logger = LoggerFactory.getLogger(SimpleHashTableNameGenerator.class);

    /**
     * 分表的子表数
     */
    public static final int subTableCount = 10;

    /**
     * 挂号记录的表名
     */
    public static final String REGISTER_RECORD_TABLE_NAME = "BIZ_REGISTER_RECORD";

    /**
     * 就诊卡的表名
     */
    public static final String MEDICAL_CARD_TABLE_NAME = "BIZ_MEDICAL_CARD";

    /**
     * 门诊记录的表名
     */
    public static final String CLINIC_RECORD_TABLE_NAME = "BIZ_CLINIC_RECORD";

    /**
     * 押金补缴记录的表名
     */
    public static final String DEPOSIT_RECORD_TABLE_NAME = "BIZ_DEPOSIT_RECORD";

    /**
     * 评价记录的表名
     */
    public static final String VOTE_TABLE_NAME = "BIZ_VOTE";

    /**
     * 评价记录的表名
     */
    public static final String EASY_HEALTH_USER_TABLE_NAME = "EH_USER";
    /**
     * 消息中心(通知中心)表名
     */
    public static final String SYS_MSG_CENTER = "SYS_MSG_CENTER";
    /**
     * 设备信息表名
     */
    public static final String EH_DEVICE_INFO = "EH_DEVICE_INFO";
    /**
     * 人表名
     */
    public static final String BIZ_PEOPLE_TABLE_NAME = "BIZ_PEOPLE";
    /**
     * 家人表名
     */
    public static final String BIZ_FAMILY_TABLE_NAME = "BIZ_FAMILY";

    /**
     * 根据userId为关键值   得到挂号记录的 hash分表
     *
     * @param userId 用户id
     * @return
     */
    public static String getRegRecordHashTable(String userId) {
        String hashTableName = getSplitTableName(REGISTER_RECORD_TABLE_NAME, userId, subTableCount, true);
        if (logger.isDebugEnabled()) {
            logger.debug("userId:{} , hashTable name:{}", new Object[]{userId, hashTableName});
        }
        return hashTableName;
    }

    /**
     * 根据userId为关键值   得到绑卡的 hash分表
     *
     * @param userId 用户id
     * @return
     */
    public static String getMedicalCardHashTable(String userId) {
        String hashTableName = getSplitTableName(MEDICAL_CARD_TABLE_NAME, userId, subTableCount, true);
        if (logger.isDebugEnabled()) {
            logger.debug("getMedicalCardHashTable name:{}", hashTableName);
        }
        return hashTableName;
    }

    public static String getClinicRecordHashTable(String userId) {
        String hashTableName = getSplitTableName(CLINIC_RECORD_TABLE_NAME, userId, subTableCount, true);
        if (logger.isDebugEnabled()) {
            logger.debug("getClinicHashTable name: {}.", hashTableName);
        }
        return hashTableName;
    }

    public static String getDepositRecordHashTable(String userId) {
        String hashTableName = getSplitTableName(DEPOSIT_RECORD_TABLE_NAME, userId, subTableCount, true);
        if (logger.isDebugEnabled()) {
            logger.debug("getDepositHashTable name: {}.", hashTableName);
        }
        return hashTableName;
    }

    public static String getVoteHashTable(String userId) {
        String hashTableName = getSplitTableName(VOTE_TABLE_NAME, userId, subTableCount, true);
        if (logger.isDebugEnabled()) {
            logger.debug("getVoteHashTable name: {}.", hashTableName);
        }
        return hashTableName;
    }

    public static String getSysMsgCenterHashTable(String userId) {
        String hashTableName = getSplitTableName(SYS_MSG_CENTER, userId, subTableCount, true);
        if (logger.isDebugEnabled()) {
            logger.debug("getSysMsgCenterHashTable name: {}.", hashTableName);
        }
        return hashTableName;
    }

    public static String getEhDeviceInfoHashTable(String userId) {
        String hashTableName = getSplitTableName(EH_DEVICE_INFO, userId, subTableCount, true);
        if (logger.isDebugEnabled()) {
            logger.debug("getEhDeviceInfoHashTable name: {}.", hashTableName);
        }
        return hashTableName;
    }

    public static String getEasyHealthUserHashTable(String account) {
        String hashTableName = getSplitTableName(EASY_HEALTH_USER_TABLE_NAME, account, subTableCount, true);
        if (logger.isDebugEnabled()) {
            logger.debug("getEasyHealthUserHashTable name: {}.", hashTableName);
        }
        return hashTableName;
    }

    public static String getPeopleHashTable(String idNo) {
        String hashTableName = getSplitTableName(BIZ_PEOPLE_TABLE_NAME, idNo, subTableCount, true);
        if (logger.isDebugEnabled()) {
            logger.debug("getPeopleHashTable name: {}.", hashTableName);
        }
        return hashTableName;
    }

    public static String getFamilyHashTable(String userId) {
        String hashTableName = getSplitTableName(BIZ_FAMILY_TABLE_NAME, userId, subTableCount, true);
        if (logger.isDebugEnabled()) {
            logger.debug("getFamilyHashTable name: {}.", hashTableName);
        }
        return hashTableName;
    }

    /**
     * 得到hsah子表名</p>
     *
     * @param tableName     原表名<br>
     * @param splitKeyVal   hash取模的关键值(根据splitKeyVal值来取模)<br>
     * @param subTableCount 要拆分子表总数<br>
     * @param isNeedUniform 是否需要均匀散列<br>
     * @return
     */
    private static String getSplitTableName(String tableName, Object splitKeyVal, Integer subTableCount, Boolean isNeedUniform) {
        long hashVal = 0;
        if (splitKeyVal instanceof Number) {
            hashVal = Integer.parseInt(splitKeyVal.toString());
        } else {
            hashVal = splitKeyVal.toString().hashCode();
        }

        //斐波那契（Fibonacci）散列
        if (isNeedUniform) {
            hashVal = (hashVal * 2654435769L) >> 28;
        }

        //避免hashVal超出 MAX_VALUE = 0x7fffffff时变为负数,取绝对值
        hashVal = Math.abs(hashVal) % subTableCount;
        String splitableName = tableName + "_" + (hashVal + 1);
        return splitableName;
    }

}
